package com.ease.platform.common.service.impl.authorization;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ease.common.util.Assertion;
import com.ease.common.util.Detect;
import com.ease.platform.authorization.callback.AuthorizationCallback;
import com.ease.platform.authorization.management.AbstractAuthorizationManagementService;
import com.ease.platform.authorization.service.AuthorizationService;
import com.ease.platform.authorization.service.impl.AbstractAuthorizationServiceImpl;
import com.ease.platform.authorization.vo.AuthorizationResult;
import com.ease.platform.delegate.service.impl.AbstractDelegateProxyServiceImpl;
import com.ease.platform.usercontext.util.UserContextThreadLocal;
import com.ease.platform.usercontext.vo.UserContext;
import com.ease.platform.usersession.service.UserSessionManagementService;
import com.ease.platform.usersession.support.UserSessionAuthorizationException;

public abstract class AbstractAuthorizationProxyServiceImpl<T extends AuthorizationService> extends AbstractDelegateProxyServiceImpl<T> implements AuthorizationService {

	private static final Log log = LogFactory.getLog(AbstractAuthorizationProxyServiceImpl.class);

	protected boolean authorizationDisabled = false;

	protected AbstractAuthorizationManagementService authorizationManagementService;

	protected UserSessionManagementService userSessionManagementService;

	public T invoke() {
		try {
			loadUserSessionIfNecessary();
			return target;
		} catch (Throwable e) {
			log.error(e.getMessage(), e);

			throw new RuntimeException(e);
		}
	}

	protected void throwUnaccessibleException() {
		throw new RuntimeException("unaccessible function, please ");
	}

	/** used by rmi service only */
	private void loadUserSessionIfNecessary() throws UserSessionAuthorizationException {
		// UserContextThreadLocal.setUserContext();// TODO;
		UserContext userContext = UserContextThreadLocal.getUserContext();
		if (null == userContext || null == userContext.getUser()) {
			long userId = userContext.getUserId();
			if (userId <= 0) {
				throw new RuntimeException("userId invalid");
			}
			// TODO get serverEndPoint from RMI service
			userSessionManagementService.loadUserSession(userId, null, null);
			userContext = UserContextThreadLocal.getUserContext();
			// copy localUserContext to & set to local
			// UserContextUtil.copy(, localUserContext);
		}
	}

	public T invoke(AuthorizationCallback authorizationCallback) {
		try {

			// loadUserSessionIfNecessary();// rmi
			//
			if (!this.isAuthorizationDisabled()) {

				Assertion.notNull(authorizationCallback, "authorizationCallback not found");

				if (!authorizationCallback.isAuthorizationDisabled() && Detect.notEmpty(authorizationCallback.operationCode())) {
					AuthorizationResult authorizationResult = authorizationManagementService.authorize(authorizationCallback);

					if (false == authorizationResult.isAuthorized()) {
						throw new RuntimeException("当前用户：" + authorizationResult.getUnAuthorizedReason().toString() + "请联系管理员！");
					}

				}
			}
			return target;

		} catch (Throwable e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage());
		}
	}
//TODO
//	/**
//	 * use invoke to get authorizationService instead
//	 *
//	 * @return the authorizationService
//	 */
//	public T getTarget() {
//		throwUnaccessibleException();
//		return (T)null;
//	}

	// public Map<Long, List<Long>> findRightMenuAndButtonActions() {
	// return
	// authorizationManagementService.findRightMenuAndButtonActions(.getUserId
	// (),
	// .getGroupIds());
	// }

	// public List<Long> findExploreIds() {
	// return
	// authorizationManagementService.findExploreIds(.getUserId().getGroupIds(),
	// );
	// }

	// public List<Long> findMainMenuIds() {
	// return
	// authorizationManagementService.findMainMenuIds(.getUserId().getGroupIds
	// (),
	// );
	// }

	// public List<Long> findPerspectViewIds() {
	// return
	// authorizationManagementService.findPerspectViewIds(.getUserId().getGroupIds
	// (),
	// );
	// }

	/**
	 * @return the authorizationManagementService
	 */
	public AbstractAuthorizationManagementService getAuthorizationManagementService() {
		return authorizationManagementService;
	}

	/**
	 * @param authorizationManagementService
	 *            the authorizationManagementService to set
	 */
	public void setAuthorizationManagementService(AbstractAuthorizationManagementService authorizationManagementService) {
		this.authorizationManagementService = authorizationManagementService;
	}

	/**
	 * @return the authorizationDisabled
	 */
	public boolean isAuthorizationDisabled() {
		return authorizationDisabled;
	}

	/**
	 * @param authorizationDisabled
	 *            the authorizationDisabled to set
	 */
	public void setAuthorizationDisabled(boolean authorizationDisabled) {
		this.authorizationDisabled = authorizationDisabled;
	}

	/**
	 * @return the userSessionManagementService
	 */
	public UserSessionManagementService getUserSessionManagementService() {
		return userSessionManagementService;
	}

	/**
	 * @param userSessionManagementService
	 *            the userSessionManagementService to set
	 */
	public void setUserSessionManagementService(UserSessionManagementService userSessionManagementService) {
		this.userSessionManagementService = userSessionManagementService;
	}

}
